import axios from 'axios'
import { API_BASE_URL } from '../config'
import storage from '../utils/storage'
import { Message } from 'element-ui'

/**
 * @type {import('axios').AxiosInstance}
 */
const Axios = axios.create({
  baseURL: API_BASE_URL,
  timeout: 10000
})

// 当前所有请求
const currentReq = new Map()

/**
 * 添加当前请求
 * @param {import('axios').AxiosRequestConfig} config
 */
function addReq(config) {
  const reqToken = [config.method, config.url, JSON.stringify(config.params), JSON.stringify(config.data)].join('&')
  config.cancelToken =
    config.cancelToken ||
    new axios.CancelToken((cancel) => {
      if (!currentReq.has(reqToken)) currentReq.set(reqToken, cancel)
    })
}

/**
 * 删除当前重复的请求
 * @param {import('axios').AxiosRequestConfig} config
 */
function delReq(config) {
  const reqToken = [config.method, config.url, JSON.stringify(config.params), JSON.stringify(config.data)].join('&')
  if (currentReq.has(reqToken)) {
    const cancel = currentReq.get(reqToken)
    cancel(reqToken)
    currentReq.delete(reqToken)
  }
}

Axios.interceptors.request.use(
  (config) => {
    delReq(config)
    addReq(config)

    if (storage.has('token')) {
      config.headers['Authorization'] = storage.get('token')
    }
    return config
  },
  (err) => Promise.reject(err)
)

Axios.interceptors.response.use(
  (response) => {
    delReq(response)
    return response
  },
  (err) => Promise.reject(err)
)

/**
 * 清空请求
 */
export function cleanReq() {
  currentReq.forEach((cancel, url) => cancel(url))
  currentReq.clear()
}

/**
 * 请求构造工厂
 * @param {import('axios').AxiosRequestConfig} config
 * @returns {Promise<{ succeed: boolean; data: any }>}
 */
export function ARFactory(config) {
  return new Promise((resolve) => {
    Axios(config).then((axiosResponse) => {
      if (!axiosResponse.data.succeed) {
        const { msg } = axiosResponse.data

        Message({
          type: 'error',
          message: msg
        })
      }

      resolve(axiosResponse.data)
    })
  })
}
